#include "display.h"

/***********************************
* GLOBAL VARIABLES
************************************/
int lcd_fd = 0;
//This pointer is supposed to be changed once it is assigned the address
//to the memory.
int *p_lcd_map = 0;

bool init_display() {
	lcd_fd = open(LCD_DEV, O_RDWR);
	if (lcd_fd == -1) {
		perror("Opening LCD failed.\n");
		exit(-1);
	}
	
	p_lcd_map = mmap(NULL, WIDTH*HEIGHT*BIT_DEPTH, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);
	if (p_lcd_map == MAP_FAILED) {
		perror("Map LCD to memory failed\n");
		exit(-1);
	}
	
	debug_info("Initialization done. \n"\
	"fd:%d \naddr of LCD: %p\n",\
	lcd_fd, p_lcd_map);
}


bool fill_screen(int color) {
	for (int x=0; x<WIDTH; x++) {
		for (int y=0; y<HEIGHT; y++){
			set_at(x, y, color);
		}
	}
	
	return 0;
}


bool set_at(int pos_x, int pos_y, int color) {
	//avoid changing original pointer unintentionally
	int *p_pos = p_lcd_map;
	p_pos += WIDTH * pos_y + pos_x;
	*p_pos = color;
	
//	debug_info("set color at x: %d, y: %d, addr: %p, color: %d\n",\
//	pos_x, pos_y, p_pos, color);
}


/***********************************
* TIME RELATIVE
************************************/
unsigned long get_time(){
	struct timeval tv;
	gettimeofday(&tv, NULL);
	
	//Part of the sec is needed to keep value increasing, 
	//as microseconds would count from zero each second.
	unsigned long cur_time=tv.tv_sec;
	//printf("sec: %ld, &:%ld, microsec: %ld", cur_time, cur_time & 0xff, tv.tv_usec);
	cur_time = 1000000*(cur_time & 0xff) + tv.tv_usec;
	//printf(" cur_time: %ld\n", cur_time);
	return cur_time;  //microseconds
}


void delay(int milliseconds){
	unsigned long last_t = get_time();
	while (last_t + milliseconds*1000 > get_time()) {/*delay*/}
}


void rate(int freq) {
	static unsigned long last_t;
	unsigned long interval = 1000000 / freq;  //microseconds
	
	//printf("interval: %d, last_t: %ld \n",interval, last_t);
	while ((last_t + interval) > get_time()) {
		for (int i=0; i<10; i++) {/*delay*/}
	}
	last_t = get_time();
	
}
